package com.onpositive.realmview.queryeditor.actions;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.IStructuredSelection;

import com.onpositive.realmview.IRealmView;
import com.onpositive.realmview.model.filtering.BasicValueFilter;
import com.onpositive.realmview.model.filtering.IUIFilter;
import com.onpositive.realmview.queryeditor.GroupNode;
import com.onpositive.realmview.queryeditor.QueryEditorPart;
import com.onpositive.realmview.queryeditor.QueryEditorPart.FilterOperationUndoable;
import com.onpositive.semantic.model.api.undo.support.UndoRedoSupport;

public class FilterExceptSelectionAction extends FilterBySelectionAction
{

	public FilterExceptSelectionAction(IStructuredSelection selection, IRealmView query, QueryEditorPart part)
	{
		super(selection, query, part);
	}
	
	
	public void run()
	{
		HashSet<IUIFilter> newFilters = new HashSet<IUIFilter>();
		Object[] elements = selection.toArray();
		for (int i = 0; i < elements.length; i++)
		{
			if (elements[i] instanceof GroupNode)
			{
				Collection<IUIFilter> filters = ((GroupNode) elements[i]).toFilters();
				newFilters.addAll(filters);
			}
		}
		List<IUIFilter> filtersList = optimizeNewFilters(newFilters);
		final List<IUIFilter> notFilters = new ArrayList<IUIFilter>(filtersList.size());
		for (Iterator<IUIFilter> iterator = filtersList.iterator(); iterator.hasNext();)
		{
			IUIFilter filter = iterator.next().clone();
			if (filter instanceof BasicValueFilter)		
			{
				filter = filter.clone();
				((BasicValueFilter) filter).setInverse(true);
				notFilters.add(filter);
			}
		}
		
		FilterOperationUndoable filterOperationUndoable = part.new FilterOperationUndoable() {
			
			@Override
			public Object execute() {
				query.filters().add(notFilters);
				part.refreshViewer();
				return Status.OK_STATUS;
			}

			@Override
			public Object undo() {
				query.filters().remove(notFilters);
				part.refreshViewer();
				return Status.OK_STATUS;
			}
		};			
		UndoRedoSupport.getUndoRedoChangeManager().execute(filterOperationUndoable);		
	}

}
